`timescale 1ns/100ps

module cm_fft5_N5 #(
    parameter C_DATA_WITH = 16
)(
    input  wire                     I_sys_clk,       // 工作时钟 100M
    input  wire                     I_data_start,    // 数据开始进入标志，与第一个数据对齐输入
    input  wire [C_DATA_WITH-1:0]   I_data_in_real,  // 数据输入，从start开始连续输入
    input  wire [C_DATA_WITH-1:0]   I_data_in_imag,  // 数据输入，从start开始连续输入
    output wire                     O_data_start,    // 数据开始输出标志与第一个数据对齐输出
    output reg  [C_DATA_WITH+2:0]   O_data_out_real, // 数据输出，从start开始连续输出
    output reg  [C_DATA_WITH+2:0]   O_data_out_imag  // 数据输出，从start开始连续输出
);

// ============================================================
// 内部参数
// ============================================================
// W05=1
// W15=0.30901699437494745-0.9510565162951535j 
// W25=-0.8090169943749473-0.5877852522924732j 
// W35=-0.8090169943749475+0.587785252292473j  
// W45=0.30901699437494723+0.9510565162951536j 

// W15 = (0.30901699437494745-0.9510565162951535j)*1024 = 316 - 974j
// W25 = (-0.8090169943749473-0.5877852522924732j)*1024 = -828- 602j
// W35 = (-0.8090169943749473+0.5877852522924732j)*1024 = -828+ 602j
// W45 = (0.30901699437494745+0.9510565162951535j)*1024 = 316 + 974j

always @(posedge I_sys_clk)
    if (S_data_start_d5) begin
        S_data_add_real_p0 <= {{3{S_data_in_real_d5[C_DATA_WITH-1]}}, S_data_in_real_d5};
        S_data_add_imag_p0 <= {{3{S_data_in_imag_d5[C_DATA_WITH-1]}}, S_data_in_imag_d5};
    end else begin
        S_data_add_real_p0 <= S_data_add_real_p0 + {{3{S_data_in_real_d5[C_DATA_WITH-1]}}, S_data_in_real_d5};
        S_data_add_imag_p0 <= S_data_add_imag_p0 + {{3{S_data_in_imag_d5[C_DATA_WITH-1]}}, S_data_in_imag_d5};
    end

// W15 =  316 - 974j
// W25 =  -828- 602j
// W35 =  -828+ 602j
// W45 =  316 + 974j
always @(*) begin
    if (S_data_start_d1) begin
        S_Wn5_real_p1 = 12'd316;
        S_Wn5_imag_p1 = -12'd974;
    end else if (S_data_start_d2) begin
        S_Wn5_real_p1 = -12'd828;
        S_Wn5_imag_p1 = -12'd602;
    end else if (S_data_start_d3) begin
        S_Wn5_real_p1 = -12'd828;
        S_Wn5_imag_p1 =  12'd602;
    end else begin
        S_Wn5_real_p1 = 12'd316;
        S_Wn5_imag_p1 = 12'd974;
    end
end

// 调用复乘 delay 6clk
cmult #(
    .AWIDTH(C_DATA_WITH),
    .BWIDTH(12)
) u0_cmult_p1 (
    .clk(I_sys_clk),
    .ar(I_data_in_real),
    .ai(I_data_in_imag),
    .br(S_Wn5_real_p1),
    .bi(S_Wn5_imag_p1),
    .pr(S_data_multp1_real),
    .pi(S_data_multp1_imag)
);

always @(posedge I_sys_clk)
    if (S_data_start_d6) begin
        S_data_add_real_p1 <= {{3{S_data_in_real_d6[C_DATA_WITH-1]}}, S_data_in_real_d6};
        S_data_add_imag_p1 <= {{3{S_data_in_imag_d6[C_DATA_WITH-1]}}, S_data_in_imag_d6};
    end else begin
        S_data_add_real_p1 <= S_data_add_real_p1 + S_data_multp1_real[(C_DATA_WITH+12):10] + S_data_multp1_real[9];
        S_data_add_imag_p1 <= S_data_add_imag_p1 + S_data_multp1_imag[(C_DATA_WITH+12):10] + S_data_multp1_imag[9];
    end

// W25 =  -828- 602j
// W45 =  316 + 974j
// W15 =  316 - 974j
// W35 =  -828+ 602j
always @(*) begin
    if (S_data_start_d2) begin
        S_Wn5_real_p2 = -12'd828;
        S_Wn5_imag_p2 = -12'd602;
    end else if (S_data_start_d3) begin
        S_Wn5_real_p2 = 12'd316;
        S_Wn5_imag_p2 = 12'd974;
    end else if (S_data_start_d4) begin
        S_Wn5_real_p2 = 12'd316;
        S_Wn5_imag_p2 = -12'd974;
    end else begin
        S_Wn5_real_p2 = -12'd828;
        S_Wn5_imag_p2 =  12'd602;
    end
end

// 调用复乘 delay 6clk
cmult #(
    .AWIDTH(C_DATA_WITH),
    .BWIDTH(12)
) u0_cmult_p2 (
    .clk(I_sys_clk),
    .ar(S_data_in_real_d1),
    .ai(S_data_in_imag_d1),
    .br(S_Wn5_real_p2),
    .bi(S_Wn5_imag_p2),
    .pr(S_data_multp2_real),
    .pi(S_data_multp2_imag)
);

always @(posedge I_sys_clk)
    if (S_data_start_d7) begin
        S_data_add_real_p2 <= {{3{S_data_in_real_d7[C_DATA_WITH-1]}}, S_data_in_real_d7};
        S_data_add_imag_p2 <= {{3{S_data_in_imag_d7[C_DATA_WITH-1]}}, S_data_in_imag_d7};
    end else begin
        S_data_add_real_p2 <= S_data_add_real_p2 + S_data_multp2_real[(C_DATA_WITH+12):10] + S_data_multp2_real[9];
        S_data_add_imag_p2 <= S_data_add_imag_p2 + S_data_multp2_imag[(C_DATA_WITH+12):10] + S_data_multp2_imag[9];
    end

// W35 =  -828+ 602j
// W15 =  316 - 974j
// W45 =  316 + 974j
// W25 =  -828- 602j
always @(*) begin
    if (S_data_start_d3) begin
        S_Wn5_real_p3 = -12'd828;
        S_Wn5_imag_p3 =  12'd602;
    end else if (S_data_start_d4) begin
        S_Wn5_real_p3 = 12'd316;
        S_Wn5_imag_p3 = -12'd974;
    end else if (S_data_start_d5) begin
        S_Wn5_real_p3 = 12'd316;
        S_Wn5_imag_p3 = 12'd974;
    end else begin
        S_Wn5_real_p3 = -12'd828;
        S_Wn5_imag_p3 = -12'd602;
    end
end

// 调用复乘 delay 6clk
cmult #(
    .AWIDTH(C_DATA_WITH),
    .BWIDTH(12)
) u0_cmult_p3 (
    .clk(I_sys_clk),
    .ar(S_data_in_real_d2),
    .ai(S_data_in_imag_d2),
    .br(S_Wn5_real_p3),
    .bi(S_Wn5_imag_p3),
    .pr(S_data_multp3_real),
    .pi(S_data_multp3_imag)
);

always @(posedge I_sys_clk)
    if (S_data_start_d8) begin
        S_data_add_real_p3 <= {{3{S_data_in_real_d8[C_DATA_WITH-1]}}, S_data_in_real_d8};
        S_data_add_imag_p3 <= {{3{S_data_in_imag_d8[C_DATA_WITH-1]}}, S_data_in_imag_d8};
    end else begin
        S_data_add_real_p3 <= S_data_add_real_p3 + S_data_multp3_real[(C_DATA_WITH+12):10] + S_data_multp3_real[9];
        S_data_add_imag_p3 <= S_data_add_imag_p3 + S_data_multp3_imag[(C_DATA_WITH+12):10] + S_data_multp3_imag[9];
    end

// W45 =  316 + 974j
// W35 =  -828+ 602j
// W25 =  -828- 602j
// W15 =  316 - 974j
always @(*) begin
    if (S_data_start_d4) begin
        S_Wn5_real_p4 = 12'd316;
        S_Wn5_imag_p4 = 12'd974;
    end else if (S_data_start_d5) begin
        S_Wn5_real_p4 = -12'd828;
        S_Wn5_imag_p4 =  12'd602;
    end else if (S_data_start_d6) begin
        S_Wn5_real_p4 = -12'd828;
        S_Wn5_imag_p4 = -12'd602;
    end else if (S_data_start_d7) begin
        S_Wn5_real_p4 = 12'd316;
        S_Wn5_imag_p4 = -12'd974;
    end
end

// 调用复乘 delay 6clk
cmult #(
    .AWIDTH(C_DATA_WITH),
    .BWIDTH(12)
) u0_cmult_p4 (
    .clk(I_sys_clk),
    .ar(S_data_in_real_d3),
    .ai(S_data_in_imag_d3),
    .br(S_Wn5_real_p4),
    .bi(S_Wn5_imag_p4),
    .pr(S_data_multp4_real),
    .pi(S_data_multp4_imag)
);

always @(posedge I_sys_clk)
    if (S_data_start_d9) begin
        S_data_add_real_p4 <= {{3{S_data_in_real_d9[C_DATA_WITH-1]}}, S_data_in_real_d9};
        S_data_add_imag_p4 <= {{3{S_data_in_imag_d9[C_DATA_WITH-1]}}, S_data_in_imag_d9};
    end else begin
        S_data_add_real_p4 <= S_data_add_real_p4 + S_data_multp4_real[(C_DATA_WITH+12):10] + S_data_multp4_real[9];
        S_data_add_imag_p4 <= S_data_add_imag_p4 + S_data_multp4_imag[(C_DATA_WITH+12):10] + S_data_multp4_imag[9];
    end

always @(posedge I_sys_clk)
    if (S_data_start_d10) begin
        O_data_out_real <= S_data_add_real_p0;
        O_data_out_imag <= S_data_add_imag_p0;
    end else if (S_data_start_d11) begin
        O_data_out_real <= S_data_add_real_p1;
        O_data_out_imag <= S_data_add_imag_p1;
    end else if (S_data_start_d12) begin
        O_data_out_real <= S_data_add_real_p2;
        O_data_out_imag <= S_data_add_imag_p2;
    end else if (S_data_start_d13) begin
        O_data_out_real <= S_data_add_real_p3;
        O_data_out_imag <= S_data_add_imag_p3;
    end else if (S_data_start_d14) begin
        O_data_out_real <= S_data_add_real_p4;
        O_data_out_imag <= S_data_add_imag_p4;
    end else begin
        O_data_out_real <= 'd0;
        O_data_out_imag <= 'd0;
    end

assign O_data_start = S_data_start_d11;

endmodule